﻿/******************************************************************************
    Copyright (C) 2020 by Zaodao(Dalian) Education Technology Co., Ltd.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "rtc-recorder.h"
#include "recorder-define.h"

#include <QDebug>
#include <QDateTime>

RTCRecorder::RTCRecorder(QObject *parent) 
    : QObject(parent), m_rtcAudioSource(nullptr), m_rtcOutputSource(nullptr), 
      m_initialized(false), m_needsOBSSetup(true), m_isRecording(false),
      m_audioProcessingRefCount(0), m_totalFrameCount(0), m_successfulFrameCount(0), m_firstFrameLogged(false)
{
    qDebug() << "[RECORDER] Constructor called";
}

RTCRecorder::~RTCRecorder()
{
    qDebug() << "[RECORDER] Destroying...";
    
    // 输出最终统计信息（如果还没有输出过）
    if (m_totalFrameCount > 0) {
        qDebug() << "[RECORDER] Final statistics - Total frames:" << m_totalFrameCount
                 << "Successful frames:" << m_successfulFrameCount
                 << "Success rate:" << (m_successfulFrameCount * 100.0 / m_totalFrameCount) << "%";
    }
    
    // 清理OBS资源
    cleanupOBSAudioChannels();
    
    qDebug() << "[RECORDER] Destroyed";
}

bool RTCRecorder::initialize(const RTCRecorderConfig &config)
{
    qDebug() << "[RECORDER] Initializing with config:";
    qDebug() << "[RECORDER]   Sample Rate:" << config.sampleRate;
    qDebug() << "[RECORDER]   Channels:" << config.channels;
    qDebug() << "[RECORDER]   Audio Format:" << config.audioFormat;
    qDebug() << "[RECORDER]   Output Gain:" << config.outputGain;
    qDebug() << "[RECORDER]   Noise Suppress:" << config.enableNoiseSuppress;
    
    m_config = config;
    
    // 检查OBS是否已初始化
    if (obs_initialized()) {
        qDebug() << "[RECORDER] OBS is already initialized, setting up audio channels";
        
        // 立即设置OBS音频通道
        if (!setupOBSAudioChannels()) {
            return false;
        }
        
        // 创建RTC音频源
        if (!createRTCAudioSource()) {
            return false;
        }
        
        // 创建RTC输出源
        if (!createRTCOutputSource()) {
            return false;
        }
        
        // 设置音频通道
        if (!setAudioChannels()) {
            return false;
        }
        
        m_needsOBSSetup = false;
    } else {
        qDebug() << "[RECORDER] OBS not initialized yet, deferring OBS setup";
        m_needsOBSSetup = true;
    }
    
    m_initialized = true;
    qDebug() << "[RECORDER] Initialized successfully";
    return true;
}

bool RTCRecorder::ensureOBSSetup()
{
    if (!m_needsOBSSetup) {
        return true;  // 已经设置过了
    }
    
    if (!obs_initialized()) {
        qDebug() << "[RECORDER] OBS still not initialized, cannot setup";
        return false;
    }
    
    qDebug() << "[RECORDER] OBS now available, performing deferred setup";
    
    // 设置OBS音频通道
    if (!setupOBSAudioChannels()) {
        return false;
    }
    
    // 创建RTC音频源
    if (!createRTCAudioSource()) {
        return false;
    }
    
    // 创建RTC输出源
    if (!createRTCOutputSource()) {
        return false;
    }
    
    // 设置音频通道
    if (!setAudioChannels()) {
        return false;
    }
    
    m_needsOBSSetup = false;
    qDebug() << "[RECORDER] Deferred OBS setup completed";
    return true;
}

void RTCRecorder::processAudioFrame(const ding::rtc::RtcEngineAudioFrame &frame)
{
    m_totalFrameCount++;
    
    // 只在第一次处理音频帧时输出详细日志
    if (!m_firstFrameLogged) {
        qDebug() << "[RECORDER] First audio frame processing"
                 << "- samples:" << frame.samples
                 << "channels:" << frame.channels
                 << "sampleRate:" << frame.samplesPerSec
                 << "bytesPerSample:" << frame.bytesPerSample
                 << "bufferValid:" << (frame.buffer ? "YES" : "NO");
        m_firstFrameLogged = true;
    }
    
    // 确保OBS设置完成
    if (!ensureOBSSetup()) {
        qWarning() << "[RECORDER] OBS setup not ready, skipping audio frame";
        return;
    }
    
    if (!m_rtcAudioSource) {
        qWarning() << "[RECORDER] RTC audio source not available";
        return;
    }
    
    if (!frame.buffer || frame.samples == 0) {
        static int emptyFrameCount = 0;
        emptyFrameCount++;
        // 只在第一次和每1000次空帧时输出日志
        if (emptyFrameCount == 1 || emptyFrameCount % 1000 == 0) {
            qDebug() << "[RECORDER] Empty audio data received (count:" << emptyFrameCount << ")";
        }
        return;
    }
    
    // 验证音频参数
    int channels = frame.channels;
    int sampleRate = frame.samplesPerSec;
    int samples = frame.samples;
    
    if (channels <= 0 || channels > 8) {
        qWarning() << "[RECORDER] Invalid channel count:" << channels;
        return;
    }
    
    // 计算音频帧数
    int audioFrames = samples;
    if (audioFrames <= 0) {
        qWarning() << "[RECORDER] No valid audio frames calculated";
        return;
    }
    
    // 创建OBS音频数据结构
    struct obs_source_audio audioData = {};
    audioData.data[0] = (const uint8_t*)frame.buffer;
    audioData.frames = audioFrames;
    audioData.speakers = SPEAKERS_STEREO;  // 假设立体声
    audioData.format = AUDIO_FORMAT_16BIT;
    audioData.samples_per_sec = sampleRate;
    audioData.timestamp = os_gettime_ns();
    
    // 输出音频数据到OBS
    obs_source_output_audio(m_rtcAudioSource, &audioData);
    
    // 统计处理的帧数 - 每5000帧输出一次统计
    m_successfulFrameCount++;
    if (m_successfulFrameCount % 5000 == 0) {
        qDebug() << "[RECORDER] Processed" << m_successfulFrameCount << "audio frames successfully sent to OBS audio source";
    }
}

bool RTCRecorder::createRTCAudioSource()
{
    if (m_rtcAudioSource) {
        qDebug() << "[RECORDER] RTC audio source already exists";
        return true;
    }
    
    qDebug() << "[RECORDER] Creating RTC audio source for RTC audio frames";
    
    // 为RTC音频帧创建一个自定义音频源（不绑定到物理设备）
    m_rtcAudioSource = obs_source_create("audio_line", "RTC Audio Input", nullptr, nullptr);
    
    if (!m_rtcAudioSource) {
        qWarning() << "[RECORDER] Failed to create RTC audio source";
        return false;
    }
    
    qDebug() << "[RECORDER] RTC audio source created successfully for RTC frames";
    return true;
}

bool RTCRecorder::setAudioChannels()
{
    if (m_rtcAudioSource) {
        qDebug() << "[RECORDER] RTC audio source set to output channel" << ZDTALK_AUDIO_INPUT_INDEX;
        obs_set_output_source(ZDTALK_AUDIO_INPUT_INDEX, m_rtcAudioSource);
    }
    
    return true;
}

bool RTCRecorder::createRTCOutputSource()
{
    if (m_rtcOutputSource) {
        return true;
    }
    
    // 创建输出音频源
    obs_data_t *settings = obs_data_create();
    obs_data_set_string(settings, "device_id", "default");
    
    m_rtcOutputSource = obs_source_create("wasapi_output_capture", "RTC Audio Output", settings, nullptr);
    obs_data_release(settings);
    
    if (!m_rtcOutputSource) {
        qWarning() << "[RECORDER] Failed to create RTC output source";
        return false;
    }
    
    qDebug() << "[RECORDER] RTC output source created successfully";
    
    // 设置输出音频源到指定通道
    if (m_rtcOutputSource) {
        qDebug() << "[RECORDER] RTC output source set to output channel" << ZDTALK_AUDIO_OUTPUT_INDEX;
        obs_set_output_source(ZDTALK_AUDIO_OUTPUT_INDEX, m_rtcOutputSource);
    }
    
    return true;
}

void RTCRecorder::cleanupOBSAudioChannels()
{
    qDebug() << "[RECORDER] Cleaning up OBS audio channels";
    
    // 清理音频源
    if (m_rtcAudioSource) {
        qDebug() << "[RECORDER] Removing RTC audio source";
        obs_set_output_source(ZDTALK_AUDIO_INPUT_INDEX, nullptr);
        obs_source_release(m_rtcAudioSource);
        m_rtcAudioSource = nullptr;
    }
    
    if (m_rtcOutputSource) {
        qDebug() << "[RECORDER] Removing RTC output source";
        obs_set_output_source(ZDTALK_AUDIO_OUTPUT_INDEX, nullptr);
        obs_source_release(m_rtcOutputSource);
        m_rtcOutputSource = nullptr;
    }
    
    // 清理其他音频通道
    obs_set_output_source(2, nullptr);
    obs_set_output_source(4, nullptr);
    obs_set_output_source(5, nullptr);
    
    qDebug() << "[RECORDER] OBS audio channels cleanup complete";
}

bool RTCRecorder::setupOBSAudioChannels()
{
    qDebug() << "[RECORDER] Setting up OBS audio channels";
    
    // 检查OBS是否已初始化
    if (!obs_initialized()) {
        qWarning() << "[RECORDER] RTCRecorder: OBS not initialized, cannot setup audio channels";
        return false;
    }
    
    // 清理可能冲突的音频通道
    obs_set_output_source(2, nullptr);
    obs_set_output_source(4, nullptr);
    obs_set_output_source(5, nullptr);
    
    qDebug() << "[RECORDER] OBS audio channels setup complete";
    return true;
}

void RTCRecorder::setOutputGain(float value)
{
    if (m_rtcOutputSource) {
        qDebug() << "[RECORDER] Setting output gain to" << value;
        obs_source_set_volume(m_rtcOutputSource, value);
    } else {
        qWarning() << "[RECORDER] RTCRecorder: RTC output source not available for output gain";
    }
}

void RTCRecorder::setOutputMute(bool mute)
{
    if (m_rtcOutputSource) {
        qDebug() << "[RECORDER] Setting output mute to" << mute;
        obs_source_set_muted(m_rtcOutputSource, mute);
    } else {
        qWarning() << "[RECORDER] RTCRecorder: RTC output source not available for mute";
    }
}

void RTCRecorder::addAudioFilter(const QString &name, const QString &type)
{
    if (m_rtcOutputSource) {
        qDebug() << "[RECORDER] Adding filter" << name << "to audio output";
        
        obs_source_t *filter = obs_source_get_filter_by_name(m_rtcOutputSource, name.toUtf8().constData());
        if (filter) {
            qDebug() << "[RECORDER] Filter" << name << "already exists";
            obs_source_release(filter);
            return;
        }
        
        obs_data_t *settings = obs_data_create();
        filter = obs_source_create(type.toUtf8().constData(), name.toUtf8().constData(), settings, nullptr);
        obs_data_release(settings);
        
        if (filter) {
            obs_source_filter_add(m_rtcOutputSource, filter);
            qDebug() << "[RECORDER] Filter" << name << "added successfully";
            obs_source_release(filter);
        } else {
            qWarning() << "[RECORDER] Failed to create filter" << name;
        }
    } else {
        qWarning() << "[RECORDER] RTC output source not available for filter";
    }
} 

// RTC音频处理控制
void RTCRecorder::startAudioProcessing()
{
    qDebug() << "[RECORDER] Start audio processing requested (refCount:" << m_audioProcessingRefCount << ")";
    
    // 增加引用计数
    m_audioProcessingRefCount++;
    
    // 只在第一次调用时启用音频帧观察者
    if (m_audioProcessingRefCount == 1) {
        // 重置统计信息
        m_totalFrameCount = 0;
        m_successfulFrameCount = 0;
        m_firstFrameLogged = false;
        
        // 确保OBS设置完成
        if (!ensureOBSSetup()) {
            qWarning() << "[RECORDER] Failed to setup OBS for audio processing";
            m_audioProcessingRefCount--;  // 失败时回退引用计数
            return;
        }
        
        // 启用音频帧观察者以开始接收RTC音频数据
        if (parent()) {
            QObject *mmService = parent();
            QMetaObject::invokeMethod(mmService, "enableAudioFrameObserver", Qt::QueuedConnection);
            qDebug() << "[RECORDER] Audio frame observer enabled (first start)";
        } else {
            qWarning() << "[RECORDER] Cannot access MMService to enable audio frame observer";
            m_audioProcessingRefCount--;  // 失败时回退引用计数
            return;
        }
        
        m_isRecording = true;
        emit audioProcessingStarted();
        qDebug() << "[RECORDER] Audio processing started (refCount now: 1)";
    } else {
        qDebug() << "[RECORDER] Audio processing already active, incremented refCount to:" << m_audioProcessingRefCount;
    }
}

void RTCRecorder::stopAudioProcessing()
{
    qDebug() << "[RECORDER] Stop audio processing requested (refCount:" << m_audioProcessingRefCount << ")";
    
    // 如果引用计数为0，说明没有启动过或已经全部停止
    if (m_audioProcessingRefCount <= 0) {
        qWarning() << "[RECORDER] Audio processing not active, ignoring stop request";
        return;
    }
    
    // 减少引用计数
    m_audioProcessingRefCount--;
    
    // 只在引用计数降为0时禁用音频帧观察者
    if (m_audioProcessingRefCount == 0) {
        // 禁用音频帧观察者以停止接收RTC音频数据
        if (parent()) {
            QObject *mmService = parent();
            QMetaObject::invokeMethod(mmService, "disableAudioFrameObserver", Qt::QueuedConnection);
            qDebug() << "[RECORDER] Audio frame observer disabled (last stop)";
        } else {
            qWarning() << "[RECORDER] Cannot access MMService to disable audio frame observer";
        }
        
        // 输出最终统计信息
        if (m_totalFrameCount > 0) {
            qDebug() << "[RECORDER] Audio processing statistics - Total frames:" << m_totalFrameCount
                     << "Successful frames:" << m_successfulFrameCount
                     << "Success rate:" << (m_successfulFrameCount * 100.0 / m_totalFrameCount) << "%";
        }
        
        m_isRecording = false;
        emit audioProcessingStopped();
        qDebug() << "[RECORDER] Audio processing fully stopped (refCount now: 0)";
    } else {
        qDebug() << "[RECORDER] Audio processing still active by other tasks, decremented refCount to:" << m_audioProcessingRefCount;
    }
}

// OBS初始化完成响应槽函数
void RTCRecorder::onOBSInitialized()
{
    qDebug() << "[RECORDER] OBS initialization completed signal received";
    
    // 调用现有的OBS设置方法
    if (ensureOBSSetup()) {
        qDebug() << "[RECORDER] OBS setup completed successfully after initialization";
    } else {
        qWarning() << "[RECORDER] OBS setup failed after initialization";
    }
} 